import { Directive, ElementRef, OnInit, Input, NgZone, SecurityContext } from '@angular/core';
import * as marked from 'marked';
import { SweetAlertService } from 'app/modules/share/services/sweet-alert.service';
import { NgControl } from '@angular/forms';
import { DomSanitizer } from '@angular/platform-browser';

@Directive({
	selector: '[mMarkdownEdit]',
})
export class MarkdownEditDirective {
	constructor(
		private el: ElementRef<HTMLTextAreaElement>,
		private sweet: SweetAlertService,
		private control: NgControl,
		private sanitizer: DomSanitizer,
	) {}

	ngOnInit() {
		this.initMarkdownEdit();
	}

	// 初始化 markdown edit 插件
	initMarkdownEdit() {
		($.fn as any).markdown.messages['zh'] = ButtonI18n;
		const additionalButtons = [
			[
				{
					name: 'groupCustomLink',
					data: [
						{
							name: 'cmdLink',
							title: 'URL/Link',
							icon: 'fa fa-link',
							callback: e => this.addLink(e),
						},
						{
							name: 'cmdImage',
							title: 'Image',
							icon: 'fa fa-image',
							callback: e => this.addImage(e),
						},
					],
				},
			],
		];
		const edit = $(this.el.nativeElement) as any;
		edit.markdown({
			iconlibrary: 'fa',
			language: 'zh',
			additionalButtons,
			reorderButtonGroups: ['groupFont', 'groupCustomLink', 'groupMisc', 'groupUtil'],
			onPreview: e => marked(e.getContent()),
			onChange: e => {
				this.control.control.setValue(e.getContent());
			},
		});
	}

	// 添加链接
	async addLink(e: MarkdownEvent) {
		const result = await this.sweet.prompt('请输入链接');
		if (result.dismiss) {
			return;
		}
		const selection: Selection = e.getSelection();
		const label = selection.text || '输入链接说明';
		const text = `[${label}](${result.value})`;
		e.replaceSelection(text);
		this.control.control.setValue(e.getContent());

		await new Promise(resolve => setTimeout(resolve, 300));
		this.el.nativeElement.focus();
		e.setSelection(selection.start + 1, selection.start + 1 + label.length);
	}

	// 添加图片
	addImage(e: MarkdownEvent) {
		const input = document.createElement('input');
		input.type = 'file';
		input.accept = 'image/*';
		input.multiple = true;
		input.addEventListener(
			'change',
			() => {
				const files = input.files;
				const texts = Array.from(files)
					.slice(0, 100)
					.map(file => {
						const url = URL.createObjectURL(file);
						const label = e.getSelection().text || file.name;
						return `![${label}](${url})`;
					});
				e.replaceSelection(texts.join(' '));
				this.control.control.setValue(e.getContent());
			},
			{ once: true },
		);
		input.click();
	}
}

// 编辑当前选择块
interface Selection {
	start: number;
	end: number;
	length: number;
	text: string;
}

// markdown插件 事件接口
interface MarkdownEvent {
	getSelection: () => Selection;
	setSelection: (start: number, end: number) => void;
	replaceSelection: (text: string) => void;
	getContent: () => string;
}
// markdown插件 i18n翻译
const ButtonI18n = {
	Bold: '粗体',
	Italic: '斜体',
	Heading: '标题',
	Image: '图片',
	List: '列表',
	Code: '代码',
	Quote: '引用',
	Preview: '预览',
	'URL/Link': '链接',
	'Unordered List': '无序列表',
	'Ordered List': '有序列表',
	'strong text': '粗体',
	'emphasized text': '强调',
	'heading text': '标题',
	'enter link description here': '输入链接说明',
	'Insert Hyperlink': 'URL地址',
	'enter image description here': '输入图片说明',
	'Insert Image Hyperlink': '图片URL地址',
	'enter image title here': '在这里输入图片标题',
	'list text here': '这里是列表文本',
	'code text here': '这里输入代码',
	'quote here': '这里输入引用文本',
};
